package com.rw.tool.util.json;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.JavaType;
import com.fasterxml.jackson.databind.ObjectMapper;

import java.lang.reflect.Type;

/**
 * 主要提供json和java对象之间的转换的方法
 */
public class JsonUtil {
    private static final ObjectMapper OBJECT_MAPPER = new ObjectMapper();

    /**
     * 最原始的json转换Java对象的方法
     *
     * @param json json字符串
     * @return java对象
     */
    public static Object toObject(String json) {
        return toObject(json, Object.class);
    }

    /**
     * json转换Java对象的重载,支持传字节码
     *
     * @param json  java对象
     * @param clazz java对象的字节码
     * @param <T>   java对象的类型
     * @return json字符串
     */
    public static <T> T toObject(String json, Class<T> clazz) {
        try {
            return OBJECT_MAPPER.readValue(json, clazz);
        } catch (JsonProcessingException e) {
            throw new JsonFormatException(e);
        }
    }


    /**
     * json转换Java对象的重载,支持TypeReference
     *
     * @param json          java对象
     * @param typeReference TypeReference
     * @param <T>           泛型
     * @return json字符串
     */
    public static <T> T toObject(String json, TypeReference<T> typeReference) {
        try {
            return OBJECT_MAPPER.readValue(json, typeReference);
        } catch (JsonProcessingException e) {
            throw new JsonFormatException(e);
        }
    }

    /**
     * java对象转换json字符串的方法
     *
     * @param object java对象
     * @return json字符串
     */
    public static String toJson(Object object) {
        try {
            return OBJECT_MAPPER.writeValueAsString(object);
        } catch (JsonProcessingException e) {
            throw new JsonFormatException(e);
        }
    }

    /**
     * 将object类型的对象转为目标类型的对象 通过class的方式
     *
     * @param object 原始对象
     * @param clazz  目标类型的对象
     * @param <T>    目标类型
     * @return 目标类型的对象
     */
    public static <T> T convertObj(Object object, Class<T> clazz) {
        return OBJECT_MAPPER.convertValue(object, clazz);
    }

    /**
     * 将object类型的对象转为目标类型的对象 通过TypeReference的方式
     *
     * @param object 原始对象
     * @param type   目标类型的对象
     * @param <T>    目标类型
     * @return 目标类型的对象
     */
    public static <T> T convertObj(Object object, TypeReference<T> type) {
        return OBJECT_MAPPER.convertValue(object, type);
    }

    /**
     * 将object类型的对象转为目标类型的对象 通过JavaType的方式
     *
     * @param object   原始对象
     * @param javaType 目标类型的对象
     * @param <T>      目标类型
     * @return 目标类型的对象
     */
    public static <T> T convertObj(Object object, JavaType javaType) {
        return OBJECT_MAPPER.convertValue(object, javaType);
    }

    /**
     * 将object类型的对象转为目标类型的对象 通过Type的方式
     *
     * @param object 原始对象
     * @param type   目标类型的对象
     * @param <T>    目标类型
     * @return 目标类型的对象
     */
    public static <T> T convertObj(Object object, Type type) {
        return convertObj(object, OBJECT_MAPPER.constructType(type));
    }

    /**
     * 获取 OBJECT_MAPPER 对象
     */
    public static ObjectMapper getMapper() {
        return OBJECT_MAPPER;
    }
}
